package examples.ejb.ejb20.basic.inventory;

import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import weblogic.ejbgen.*;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Hashtable;
import java.util.Set;


/**
 * InventoryBean is a stateless Session Bean. This bean illustrates:
 * <ul>
 * <li> No persistence of state between calls to the Session Bean
 * <li> Looking up values from the Environment
 * </ul>
 *
 * @author Copyright (c) 1999-2008 by BEA Systems, Inc. All Rights Reserved.
 */
@EnvEntries({
    @EnvEntry(name = "WEBL",
              type = "java.lang.Double",
              value = "10.0"),
    @EnvEntry(name = "minLimit",
              type = "java.lang.Integer",
              value = "6"),
    @EnvEntry(name = "maxLimit",
              type = "java.lang.Integer",
              value = "15")
})
@FileGeneration(remoteClass = Constants.Bool.TRUE,
                localHome = Constants.Bool.FALSE,
                remoteHome = Constants.Bool.TRUE,
                remoteClassName = "Inventory",
                remoteHomeName = "InventoryHome",
                localClass = Constants.Bool.FALSE)
@JarSettings(ejbClientJar = "ejb20_basic_inventory_client.jar")
@JndiName(remote = "ejb20-inventory-InventoryHome")
@Session(maxBeansInFreePool = "1000",
         initialBeansInFreePool = "0",
         transTimeoutSeconds = "0",
         type = Session.SessionType.STATELESS,
         defaultTransaction = Constants.TransactionAttribute.REQUIRED,
         ejbName = "inventory",
         enableCallByReference = Constants.Bool.TRUE)
public class InventoryBean implements SessionBean {

  private static final boolean VERBOSE = false;
  private SessionContext ctx;
  
/////////////////////////////////////////////////////////////////////////////////////
	private static final String INVENTORYINPUTTEXT = "C:/bea/wlserver_10.3/inventory_input.txt";
	private static final String STOCKTEXT = "C:/bea/wlserver_10.3/stock.txt";
	private static final Hashtable<String,String[]> inventoryTable = new Hashtable<String,String[]>();
	
	/**
	 * @param args
	 */
	
	static {
		try {
			loadHashTable();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	private static void loadHashTable() throws FileNotFoundException{
		String line=null;
		Pattern extPattern=Pattern.compile("(.*)\\*(.*)\\*(.*)\\*",Pattern.CASE_INSENSITIVE);
		BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(
				new FileInputStream(STOCKTEXT))));	
		try {
			while ((line=reader.readLine())!=null){
				Matcher matcher = extPattern.matcher(line.trim());
				while (matcher.find()){
					String[] rec = new String[]{matcher.group(1),matcher.group(2),matcher.group(3)} ;
					inventoryTable.put( matcher.group(1)+ matcher.group(2),rec);
				}
			}		
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@RemoteMethod()
	public String getINVENTORYINPUTTEXT(){
		return INVENTORYINPUTTEXT;
	}
	
	@RemoteMethod()
	public String getSTOCKTEXT(){
		return STOCKTEXT;
	}

	@RemoteMethod()
	public Hashtable<String,String[]> getInventoryTable(){
		return inventoryTable;
	}
	
	@RemoteMethod()
	public String[] getTitle (String theKey){
		String[] titleInfo = inventoryTable.get(theKey);
		return(titleInfo);
	}
	
	@RemoteMethod()
	public void writeInventoryTable(){
		File newFile = new File(STOCKTEXT);
		PrintWriter out;
		try {
			out = new PrintWriter(newFile);
			for (String thisKey : inventoryTable.keySet()){
				String[] thisRec = inventoryTable.get(thisKey);
				String stringToWrite = thisRec[0]+"*"+thisRec[1]+"*"+thisRec[2]+"*";
				out.println(stringToWrite);
			}
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} 
	}  
	
	@RemoteMethod()
	public boolean add (String pub_id, String title, int qty) {
		String[] existingTitle = getTitle(pub_id+title); 
		int currentNumberInStock = 0;
		System.out.println("adding "+pub_id+" "+title+" "+qty);
		
		if (getTitle(pub_id+title)!=null){
			currentNumberInStock = Integer.parseInt(existingTitle[2]);
			inventoryTable.remove(pub_id+title);
		}
		String[] rec = new String[]{pub_id,title,Integer.toString(qty+currentNumberInStock)};
		
		inventoryTable.put(pub_id+title,rec);	
		writeInventoryTable();
		return(true);		
	}
	
	@RemoteMethod()
	public boolean remove (String pub_id, String title, int qty){
		String[] existingTitle = getTitle(pub_id+title);
		boolean response = true;
		System.out.println("removing "+pub_id+" "+title+" "+qty);
		
		if (existingTitle==null){
			//not in stock
			return false;
		}
		int newNumberInStock = Integer.parseInt(existingTitle[2])-qty;
		if (newNumberInStock < 0) {
			newNumberInStock=0;
			response=false;
		}	
		inventoryTable.remove(pub_id+title);		
		if (newNumberInStock>0){
			String[] rec = new String[]{pub_id,title,Integer.toString(newNumberInStock)};
			inventoryTable.put(pub_id+title,rec);	
		}
		writeInventoryTable();
		return(response);		
	}

  // You might also consider using WebLogic's log service
  private void log(String s) {
    if (VERBOSE) System.out.println(s);
  } 
  
  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   *
   */
  public void ejbActivate() {
    log("ejbActivate called");
  }

  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   *
   */
  public void ejbRemove() {
    log("ejbRemove called");
  }

  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   *
   */
  public void ejbPassivate() {
    log("ejbPassivate called");
  }

  /**
   * Sets the session context.
   *
   * @param ctx               SessionContext Context for session
   */
  public void setSessionContext(SessionContext ctx) {
    log("setSessionContext called");
    this.ctx = ctx;
  }

  /**
   * This method corresponds to the create method in the home interface
   * "InventoryHome.java".
   * The parameter sets of the two methods are identical. When the client calls
   * <code>InventoryHome.create()</code>, the container allocates an instance of 
   * the EJBean and calls <code>ejbCreate()</code>.
   *
   * @exception               javax.ejb.CreateException if there is
   *                          a communications or systems failure
   * @see                     examples.ejb.ejb20.basic.statelessSession.Trader
   */
  public void ejbCreate () throws CreateException {

  }


}
